package com.eudon.genius.api.core.parser;

import com.eudon.genius.api.core.api.DocParser;
import com.eudon.genius.api.core.dto.AppInfo;
import com.eudon.genius.api.core.dto.PropertiesDto;
import com.eudon.genius.api.core.parser.component.*;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseResult;
import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * 基于JavaParser的文档解析器实现
 * 负责协调各个组件完成完整的API文档解析
 *
 * @author eudon
 * @since 2025/9/25
 */
@Slf4j
public class JavaParserDocParser implements DocParser {

    private final JavaParser javaParser;
    private final CombinedTypeSolver combinedTypeSolver;
    private final PackageScanner packageScanner;
    private final ApiInfoBuilder apiInfoBuilder;
    private final PropertiesDto propertiesDto;

    public JavaParserDocParser(PropertiesDto propertiesDto) {
        // 先创建类型解析器
        this.combinedTypeSolver = new CombinedTypeSolver();
        this.combinedTypeSolver.add(new ReflectionTypeSolver()); // 解析JDK类
        this.propertiesDto = propertiesDto;
        // 创建JavaParser
        this.javaParser = createJavaParser();
        this.packageScanner = new PackageScanner();
        JavaDocParser javaDocParser = new JavaDocParser();
        AnnotationParser annotationParser = new AnnotationParser();
        TypeResolver typeResolver = new TypeResolver();
        ParameterParser parameterParser = new ParameterParser(typeResolver);
        this.apiInfoBuilder = new ApiInfoBuilder(
                propertiesDto,
                javaDocParser,
                annotationParser,
                parameterParser,
                typeResolver
        );
    }

    /**
     * 创建配置好的JavaParser实例
     */
    private JavaParser createJavaParser() {
        // 配置Symbol Solver
        JavaSymbolSolver symbolSolver = new JavaSymbolSolver(combinedTypeSolver);

        // 创建JavaParser配置
        ParserConfiguration config = new ParserConfiguration();
        config.setSymbolResolver(symbolSolver);

        return new JavaParser(config);
    }

    @Override
    public AppInfo parsePackage() {
        String basePackage = propertiesDto.getBasePackage();
        Path sourcePath = Paths.get(propertiesDto.getSourcePath());
                log.debug("开始解析包: {}, 源码路径: {}", basePackage, sourcePath);

        try {
            // 添加源码路径到类型解析器
            addSourcePathsToTypeSolver(sourcePath);

            // 扫描包下的所有Java文件
            List<Path> javaFiles = packageScanner.scanPackage(basePackage, sourcePath);
            log.info("找到 {} 个Java文件", javaFiles.size());

            // 解析所有Java文件
            return parseJavaFiles(javaFiles);

        } catch (Exception e) {
            log.error("解析包 {} 时发生错误", basePackage, e);
            return createEmptyAppInfo();
        }
    }

    /**
     * 将源码路径添加到类型解析器中
     */
    private void addSourcePathsToTypeSolver(Path sourcePath) {
        try {
            // 直接使用存储的CombinedTypeSolver实例
            if (Files.exists(sourcePath) && Files.isDirectory(sourcePath)) {
                try {
                    combinedTypeSolver.add(new JavaParserTypeSolver(sourcePath));
                    log.debug("成功添加源码路径到类型解析器: {}", sourcePath);
                } catch (Exception e) {
                    log.warn("添加源码路径失败: {}, 错误: {}", sourcePath, e.getMessage());
                }
            } else {
                log.warn("源码路径不存在或不是目录: {}", sourcePath);
            }

        } catch (Exception e) {
            log.error("添加源码路径到类型解析器时发生错误", e);
        }
    }

    /**
     * 解析Java文件列表
     */
    private AppInfo parseJavaFiles(List<Path> javaFiles) {
        List<CompilationUnit> compilationUnits = null;
        try {
            compilationUnits = new ArrayList<>();

            // 解析所有Java文件为AST
            for (Path javaFile : javaFiles) {
                try {
                    ParseResult<CompilationUnit> parseResult = javaParser.parse(javaFile);
                    if (parseResult.isSuccessful() && parseResult.getResult().isPresent()) {
                        compilationUnits.add(parseResult.getResult().get());
                    } else {
                        log.warn("解析文件失败: {}, 错误: {}", javaFile, parseResult.getProblems());
                    }
                } catch (IOException e) {
                    log.error("读取文件失败: {}", javaFile, e);
                }
            }

            log.info("找到 {} 个类", compilationUnits.size());
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            apiInfoBuilder.getTypeResolver().clearCache();
        }

        // 构建API信息
        return apiInfoBuilder.buildAppInfo(compilationUnits);
    }

    /**
     * 创建空的应用信息
     */
    private AppInfo createEmptyAppInfo() {
        AppInfo appInfo = new AppInfo();
        appInfo.setAppName("Unknown");
        appInfo.setGroups(new ArrayList<>());
        return appInfo;
    }
}